package com.linc.ds;

public class CircleList<E> extends MyLinkedList<E> {

  private Node<E> tailOfDelete = null;

  public CircleList() {
    super();
  }

  @Override
  public Boolean insertAtPos(E e, int pos) {
    var newNode = new Node<>(e);

    // 空链表插入第一个节点
    if (getLen() == 0) {
      setHead(newNode);
      setNext(getHead(), getHead());
    } else if (pos == 0) {
      // 插入位置0
      newNode.next = getHead();
      var t = getHead();
      for (int i = 0; i < getLen() - 1; i++) {
        t = t.next;
      }
      setHead(newNode);
      // 尾节点指向新节点
      t.next = getHead();
    } else {
      // 插入位置不是0
      // 假设现在长度为2, 在位置1(pos)插入, 需要找到位置为0的节点
      var cu = getHead();
      for (int i = 0; i < pos - 1; i++) {
        cu = cu.next;
      }
      newNode.next = cu.next;
      cu.next = newNode;
    }
    incLen();
    return true;
  }

  @Override
  public E delete(int pos) {
    if (isEmpty()) return null;

    var cu = getHead();
    for (int i = 1; i < pos; i++) {
      cu = cu.next;
    }

    // 此时cu是上一个节点
    var r = cu.next.data;
    if (cu.next == getHead()) {
      // 删除头节点
      if (getLen() == 1) {
        // 只有一个节点
        setHead(null);
      } else {
        setNext(cu, getNode(1));
        setHead(cu.next);
      }
    } else {
      // 删除非头节点
      // 一定是有多个节点了
      cu.next = cu.next.next;
    }
    decLen();
    return r;
  }

  /**
   * 从某个位置cu开始, 删除指定offset的元素
   *
   * @param offset - 偏移量
   * @return 删除的元素
   */
  public E circleDelete(int offset) {
    if (tailOfDelete == null) return null;

    if (getLen() == 1) {

      var r = getData(0);
      setHead(null);
      decLen();
      return r;
    }

    for (int i = 1; i < offset; i++) {
      tailOfDelete = tailOfDelete.next;
    }
    E r = tailOfDelete.next.data;
    if (tailOfDelete.next != getHead()) {
      tailOfDelete.next = tailOfDelete.next.next;
    } else {
      // 删除头节点
      setHead(tailOfDelete.next.next);
      tailOfDelete.next = getHead();
    }
    decLen();
    return r;
  }

  /** 设置尾节点 */
  public void setTailOfDelete() {
    tailOfDelete = getHead();

    if (tailOfDelete == null) return;
    // 找到尾节点
    for (int i = 0; i < getLen() - 1; i++) {
      tailOfDelete = tailOfDelete.next;
    }
  }
}
